from datetime import datetime

currentSecond= datetime.now().second
currentMinute = datetime.now().minute
currentHour = datetime.now().hour

currentDay = datetime.now().day
currentMonth = datetime.now().month
currentYear = datetime.now().year
import pandas as pd
import xlrd

url = "https://www.ecdc.europa.eu/sites/default/files/documents/COVID-19-geographic-disbtribution-worldwide-"+str(currentYear)+"-0"+str(currentMonth)+"-"+str(currentDay)+".xlsx"
#df = pd.read_csv(url)
data = pd.read_excel(url)

data.head()
dateRep day month year cases deaths countriesAndTerritories geoId countryterritoryCode popData2018
0 2020-03-31 31 3 2020 27 0 Afghanistan AF AFG 37172386.0
1 2020-03-30 30 3 2020 8 1 Afghanistan AF AFG 37172386.0
2 2020-03-29 29 3 2020 15 1 Afghanistan AF AFG 37172386.0
3 2020-03-28 28 3 2020 16 1 Afghanistan AF AFG 37172386.0
4 2020-03-27 27 3 2020 0 0 Afghanistan AF AFG 37172386.0
data['dateRep'].max()
Timestamp('2020-03-31 00:00:00')
data.dtypes
dateRep                    datetime64[ns]
day                                 int64
month                               int64
year                                int64
cases                               int64
deaths                              int64
countriesAndTerritories            object
geoId                              object
countryterritoryCode               object
popData2018                       float64
dtype: object
import numpy as np
data['dateRep']= pd.to_datetime(data['dateRep']) 
#data['dateRep']= pd.Series(data['dateRep'])
data_min = data[data.cases > 0].reset_index(drop=True)
data_min.head()
dateRep day month year cases deaths countriesAndTerritories geoId countryterritoryCode popData2018
0 2020-03-31 31 3 2020 27 0 Afghanistan AF AFG 37172386.0
1 2020-03-30 30 3 2020 8 1 Afghanistan AF AFG 37172386.0
2 2020-03-29 29 3 2020 15 1 Afghanistan AF AFG 37172386.0
3 2020-03-28 28 3 2020 16 1 Afghanistan AF AFG 37172386.0
4 2020-03-26 26 3 2020 33 0 Afghanistan AF AFG 37172386.0
min_date = data_min.groupby(['countriesAndTerritories'], as_index=False)["dateRep"].min()
min_date = min_date.rename(columns={'dateRep': 'min_date'})
min_date.head()
countriesAndTerritories min_date
0 Afghanistan 2020-02-25
1 Albania 2020-03-09
2 Algeria 2020-02-26
3 Andorra 2020-03-03
4 Angola 2020-03-22
df = data.merge(min_date, on='countriesAndTerritories', how='left')
df.head()
dateRep day month year cases deaths countriesAndTerritories geoId countryterritoryCode popData2018 min_date
0 2020-03-31 31 3 2020 27 0 Afghanistan AF AFG 37172386.0 2020-02-25
1 2020-03-30 30 3 2020 8 1 Afghanistan AF AFG 37172386.0 2020-02-25
2 2020-03-29 29 3 2020 15 1 Afghanistan AF AFG 37172386.0 2020-02-25
3 2020-03-28 28 3 2020 16 1 Afghanistan AF AFG 37172386.0 2020-02-25
4 2020-03-27 27 3 2020 0 0 Afghanistan AF AFG 37172386.0 2020-02-25
#df['DateRep']= pd.to_datetime(df['DateRep']) 
df['min_date']= pd.to_datetime(df['min_date']) 
df.head()
dateRep day month year cases deaths countriesAndTerritories geoId countryterritoryCode popData2018 min_date
0 2020-03-31 31 3 2020 27 0 Afghanistan AF AFG 37172386.0 2020-02-25
1 2020-03-30 30 3 2020 8 1 Afghanistan AF AFG 37172386.0 2020-02-25
2 2020-03-29 29 3 2020 15 1 Afghanistan AF AFG 37172386.0 2020-02-25
3 2020-03-28 28 3 2020 16 1 Afghanistan AF AFG 37172386.0 2020-02-25
4 2020-03-27 27 3 2020 0 0 Afghanistan AF AFG 37172386.0 2020-02-25
df['days'] = (df['dateRep'] - df['min_date']) / np.timedelta64(1, 'D')
df.head()
dateRep day month year cases deaths countriesAndTerritories geoId countryterritoryCode popData2018 min_date days
0 2020-03-31 31 3 2020 27 0 Afghanistan AF AFG 37172386.0 2020-02-25 35.0
1 2020-03-30 30 3 2020 8 1 Afghanistan AF AFG 37172386.0 2020-02-25 34.0
2 2020-03-29 29 3 2020 15 1 Afghanistan AF AFG 37172386.0 2020-02-25 33.0
3 2020-03-28 28 3 2020 16 1 Afghanistan AF AFG 37172386.0 2020-02-25 32.0
4 2020-03-27 27 3 2020 0 0 Afghanistan AF AFG 37172386.0 2020-02-25 31.0
df.sort_values(by=['countriesAndTerritories', 'dateRep'], inplace=True)
df.head()
dateRep day month year cases deaths countriesAndTerritories geoId countryterritoryCode popData2018 min_date days
81 2019-12-31 31 12 2019 0 0 Afghanistan AF AFG 37172386.0 2020-02-25 -56.0
80 2020-01-01 1 1 2020 0 0 Afghanistan AF AFG 37172386.0 2020-02-25 -55.0
79 2020-01-02 2 1 2020 0 0 Afghanistan AF AFG 37172386.0 2020-02-25 -54.0
78 2020-01-03 3 1 2020 0 0 Afghanistan AF AFG 37172386.0 2020-02-25 -53.0
77 2020-01-04 4 1 2020 0 0 Afghanistan AF AFG 37172386.0 2020-02-25 -52.0
#df = pd.read_csv(StringIO(data))
cumsums = df.groupby(['countriesAndTerritories', 'dateRep'])["cases"].sum().fillna(0).groupby(level=0).cumsum()
df.set_index(['countriesAndTerritories', 'dateRep'], inplace=True)
df['cum_cases'] = cumsums
df.reset_index(inplace=True)
df.head(100)
countriesAndTerritories dateRep day month year cases deaths geoId countryterritoryCode popData2018 min_date days cum_cases
0 Afghanistan 2019-12-31 31 12 2019 0 0 AF AFG 37172386.0 2020-02-25 -56.0 0
1 Afghanistan 2020-01-01 1 1 2020 0 0 AF AFG 37172386.0 2020-02-25 -55.0 0
2 Afghanistan 2020-01-02 2 1 2020 0 0 AF AFG 37172386.0 2020-02-25 -54.0 0
3 Afghanistan 2020-01-03 3 1 2020 0 0 AF AFG 37172386.0 2020-02-25 -53.0 0
4 Afghanistan 2020-01-04 4 1 2020 0 0 AF AFG 37172386.0 2020-02-25 -52.0 0
... ... ... ... ... ... ... ... ... ... ... ... ... ...
95 Albania 2020-03-22 22 3 2020 6 0 AL ALB 2866376.0 2020-03-09 13.0 76
96 Albania 2020-03-23 23 3 2020 13 0 AL ALB 2866376.0 2020-03-09 14.0 89
97 Albania 2020-03-24 24 3 2020 11 2 AL ALB 2866376.0 2020-03-09 15.0 100
98 Albania 2020-03-25 25 3 2020 23 1 AL ALB 2866376.0 2020-03-09 16.0 123
99 Albania 2020-03-26 26 3 2020 23 0 AL ALB 2866376.0 2020-03-09 17.0 146

100 rows × 13 columns

cumsums = df.groupby(['countriesAndTerritories', 'dateRep'])["deaths"].sum().fillna(0).groupby(level=0).cumsum()
df.set_index(['countriesAndTerritories', 'dateRep'], inplace=True)
df['cum_deaths'] = cumsums
df.reset_index(inplace=True)
df.head(100)
countriesAndTerritories dateRep day month year cases deaths geoId countryterritoryCode popData2018 min_date days cum_cases cum_deaths
0 Afghanistan 2019-12-31 31 12 2019 0 0 AF AFG 37172386.0 2020-02-25 -56.0 0 0
1 Afghanistan 2020-01-01 1 1 2020 0 0 AF AFG 37172386.0 2020-02-25 -55.0 0 0
2 Afghanistan 2020-01-02 2 1 2020 0 0 AF AFG 37172386.0 2020-02-25 -54.0 0 0
3 Afghanistan 2020-01-03 3 1 2020 0 0 AF AFG 37172386.0 2020-02-25 -53.0 0 0
4 Afghanistan 2020-01-04 4 1 2020 0 0 AF AFG 37172386.0 2020-02-25 -52.0 0 0
... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
95 Albania 2020-03-22 22 3 2020 6 0 AL ALB 2866376.0 2020-03-09 13.0 76 2
96 Albania 2020-03-23 23 3 2020 13 0 AL ALB 2866376.0 2020-03-09 14.0 89 2
97 Albania 2020-03-24 24 3 2020 11 2 AL ALB 2866376.0 2020-03-09 15.0 100 4
98 Albania 2020-03-25 25 3 2020 23 1 AL ALB 2866376.0 2020-03-09 16.0 123 5
99 Albania 2020-03-26 26 3 2020 23 0 AL ALB 2866376.0 2020-03-09 17.0 146 5

100 rows × 14 columns

df['date_int'] = (df['year'] * 10000 + df['month'] * 100 + df['day']).astype(int)
df = df.rename(columns={'countriesAndTerritories': 'pais'})
df = df.sort_values(by=['date_int', 'pais'])
max_cases = df.groupby(['pais'], as_index=False)["cum_cases"].max()
max_cases = max_cases.rename(columns={'cum_cases': 'max_cases'})
df = df.merge(max_cases, on='pais', how='left')
df.head()
pais dateRep day month year cases deaths geoId countryterritoryCode popData2018 min_date days cum_cases cum_deaths date_int max_cases
0 Afghanistan 2019-12-31 31 12 2019 0 0 AF AFG 37172386.0 2020-02-25 -56.0 0 0 20191231 141
1 Algeria 2019-12-31 31 12 2019 0 0 DZ DZA 42228429.0 2020-02-26 -57.0 0 0 20191231 511
2 Armenia 2019-12-31 31 12 2019 0 0 AM ARM 2951776.0 2020-03-01 -61.0 0 0 20191231 482
3 Australia 2019-12-31 31 12 2019 0 0 AU AUS 24992369.0 2020-01-25 -25.0 0 0 20191231 4557
4 Austria 2019-12-31 31 12 2019 0 0 AT AUT 8847037.0 2020-02-26 -57.0 0 0 20191231 9618
df = df.sort_values(by=['date_int', 'geoId'])
df['days'].min()
0.0
df['dateRep'].max()
Timestamp('2020-03-31 00:00:00')
today = pd.to_datetime('today')
df = df.where(df['dateRep'] < today)
df = df.where(df['days'] >= 0)
df = df.dropna()
df.dtypes
pais                            object
dateRep                 datetime64[ns]
day                            float64
month                          float64
year                           float64
cases                          float64
deaths                         float64
geoId                           object
countryterritoryCode            object
popData2018                    float64
min_date                datetime64[ns]
days                           float64
cum_cases                      float64
cum_deaths                     float64
date_int                       float64
max_cases                      float64
dtype: object
import pandas as pd
import altair as alt

Casos acumulados por país

Evolución Diaria

# select a point for which to provide details-on-demand
source = df.where(df['max_cases'] >= 10000)
label = alt.selection_single(
    encodings=['x'], # limit selection to x-axis value
    on='mouseover',  # select on mouseover events
    nearest=True,    # select data point nearest the cursor
    empty='none'     # empty selection includes no data points
)

# define our base line chart of stock prices
base = alt.Chart().mark_line().encode(
    alt.X('dateRep:T'),
    alt.Y('cum_cases:Q', scale=alt.Scale(type='log')),
    alt.Color('pais:N')
)

alt.layer(
    base, # base line chart
    
    # add a rule mark to serve as a guide line
    alt.Chart().mark_rule(color='#aaa').encode(
        x='dateRep:T'
    ).transform_filter(label),
    
    # add circle marks for selected time points, hide unselected points
    base.mark_circle().encode(
        opacity=alt.condition(label, alt.value(1), alt.value(0))
    ).add_selection(label),

    # add white stroked text to provide a legible background for labels
    base.mark_text(align='left', dx=5, dy=-5, stroke='white', strokeWidth=5).encode(
        text='cum_cases:Q'
    ).transform_filter(label),
    
    base.mark_text(align='left', dx=35, dy=-5, stroke='white', strokeWidth=5).encode(
        text='pais:N'
    ).transform_filter(label),

    # add text labels for stock prices
    base.mark_text(align='left', dx=5, dy=-5).encode(
        text='cum_cases:Q'
    ).transform_filter(label),
    
    base.mark_text(align='left', dx=35, dy=-5).encode(
        text='pais:N'
    ).transform_filter(label),
    
    data=source
).properties(
    width=700,
    height=400
)

Evolución por día del primer caso detectado en el país

# select a point for which to provide details-on-demand
source = df.where(df['max_cases'] >= 1000)
label = alt.selection_single(
    encodings=['x'], # limit selection to x-axis value
    on='mouseover',  # select on mouseover events
    nearest=True,    # select data point nearest the cursor
    empty='none'     # empty selection includes no data points
)

# define our base line chart of stock prices
base = alt.Chart().mark_line().encode(
    alt.X('days:Q'),
    alt.Y('cum_cases:Q', scale=alt.Scale(type='log')),
    alt.Color('pais:N')
)

alt.layer(
    base, # base line chart
    
    # add a rule mark to serve as a guide line
    alt.Chart().mark_rule(color='#aaa').encode(
        x='days:Q'
    ).transform_filter(label),
    
    # add circle marks for selected time points, hide unselected points
    base.mark_circle().encode(
        opacity=alt.condition(label, alt.value(1), alt.value(0))
    ).add_selection(label),

    # add white stroked text to provide a legible background for labels
    base.mark_text(align='left', dx=5, dy=-5, stroke='white', strokeWidth=2).encode(
        text='cum_cases:Q'
    ).transform_filter(label),

    # add text labels for stock prices
    base.mark_text(align='left', dx=5, dy=-5).encode(
        text='cum_cases:Q'
    ).transform_filter(label),
    
    base.mark_text(align='left', dx=40, dy=-5).encode(
        text='pais:N'
    ).transform_filter(label),
    
    data=source
).properties(
    width=700,
    height=400
)
source = df.where(df['cases'] > 0)
source = source.where(df['max_cases'] >= 30000)
alt.Chart(source).mark_line(point=True).encode(
    alt.X('cum_cases:Q', scale=alt.Scale(type='log')),
    alt.Y('cases:Q', scale=alt.Scale(type='log')),
    color='pais',
    tooltip=['pais:N', 'days:Q', 'cum_cases:Q']
).properties(
    width=700,
    height=400)
# select a point for which to provide details-on-demand
source = df.where(df['cases'] > 0)
source = source.where(df['max_cases'] >= 30000)
label = alt.selection_single(
    encodings=['x'], # limit selection to x-axis value
    on='mouseover',  # select on mouseover events
    nearest=True,    # select data point nearest the cursor
    empty='none'     # empty selection includes no data points
)

# define our base line chart of stock prices
base = alt.Chart().mark_line(point=True).encode(
    alt.X('cum_cases:Q', axis=alt.Axis(grid=False), scale=alt.Scale(type='log')),
    alt.Y('cases:Q', axis=alt.Axis(grid=False), scale=alt.Scale(type='log')),
    alt.Color('pais:N')
)

alt.layer(
    base, # base line chart
    
    # add a rule mark to serve as a guide line
    alt.Chart().mark_rule(color='#aaa').encode(
        x='cum_cases:Q'
    ).transform_filter(label),
    
    # add circle marks for selected time points, hide unselected points
    base.mark_circle().encode(
        opacity=alt.condition(label, alt.value(1), alt.value(0))
    ).add_selection(label),

    # add white stroked text to provide a legible background for labels
    base.mark_text(align='left', dx=5, dy=-5, stroke='white', strokeWidth=2).encode(
        text='cum_cases:Q'
    ).transform_filter(label),

    # add text labels for stock prices
    base.mark_text(align='left', dx=5, dy=-5).encode(
        text='cum_cases:Q'
    ).transform_filter(label),
    
    base.mark_text(align='left', dx=40, dy=-5).encode(
        text='pais:N'
    ).transform_filter(label),
    
    data=source
).properties(
    width=700,
    height=400
)

Decesos acumulados por país

# select a point for which to provide details-on-demand
source = df#.where(df['max_cases'] >= 1000)
label = alt.selection_single(
    encodings=['x'], # limit selection to x-axis value
    on='mouseover',  # select on mouseover events
    nearest=True,    # select data point nearest the cursor
    empty='none'     # empty selection includes no data points
)

# define our base line chart of stock prices
base = alt.Chart().mark_line().encode(
    alt.X('dateRep:T'),
    alt.Y('cum_deaths:Q'),
    alt.Color('pais:N')
)

alt.layer(
    base, # base line chart
    
    # add a rule mark to serve as a guide line
    alt.Chart().mark_rule(color='#aaa').encode(
        x='dateRep:T'
    ).transform_filter(label),
    
    # add circle marks for selected time points, hide unselected points
    base.mark_circle().encode(
        opacity=alt.condition(label, alt.value(1), alt.value(0))
    ).add_selection(label),

    # add white stroked text to provide a legible background for labels
    base.mark_text(align='right', dx=5, dy=-5, stroke='white', strokeWidth=5).encode(
        text='cum_deaths:Q'
    ).transform_filter(label),
    
    base.mark_text(align='right', dx=5, dy=-15, stroke='white', strokeWidth=5).encode(
        text='pais:N'
    ).transform_filter(label),

    # add text labels for stock prices
    base.mark_text(align='right', dx=5, dy=-5).encode(
        text='cum_deaths:Q'
    ).transform_filter(label),
    
    base.mark_text(align='right', dx=5, dy=-15).encode(
        text='pais:N'
    ).transform_filter(label),
    
    data=source
).properties(
    width=700,
    height=400
).interactive()
# select a point for which to provide details-on-demand
source = df#.where(df['max_cases'] >= 1000)
label = alt.selection_single(
    encodings=['x'], # limit selection to x-axis value
    on='mouseover',  # select on mouseover events
    nearest=True,    # select data point nearest the cursor
    empty='none'     # empty selection includes no data points
)

# define our base line chart of stock prices
base = alt.Chart().mark_line().encode(
    alt.X('days:Q'),
    alt.Y('cum_deaths:Q'),
    alt.Color('pais:N')
)

alt.layer(
    base, # base line chart
    
    # add a rule mark to serve as a guide line
    alt.Chart().mark_rule(color='#aaa').encode(
        x='days:Q'
    ).transform_filter(label),
    
    # add circle marks for selected time points, hide unselected points
    base.mark_circle().encode(
        opacity=alt.condition(label, alt.value(1), alt.value(0))
    ).add_selection(label),

    # add white stroked text to provide a legible background for labels
    base.mark_text(align='left', dx=5, dy=-5, stroke='white', strokeWidth=2).encode(
        text='cum_deaths:Q'
    ).transform_filter(label),
    
    base.mark_text(align='left', dx=37, dy=-5, stroke='white', strokeWidth=2).encode(
        text='pais:N'
    ).transform_filter(label),

    # add text labels for stock prices
    base.mark_text(align='left', dx=5, dy=-5).encode(
        text='cum_deaths:Q'
    ).transform_filter(label),
    
    base.mark_text(align='left', dx=37, dy=-5).encode(
        text='pais:N'
    ).transform_filter(label),
    
    data=source
).properties(
    width=700,
    height=400
)
date = data['dateRep'].max()
source = df.where(df['dateRep'] >= date)
source = source.where(source['max_cases'] >= 1000)

alt.Chart(source).mark_circle(size=100).encode(
    alt.X('cum_cases:Q'),
    alt.Y('cum_deaths:Q', scale=alt.Scale(type='log')),
    color='pais',
    tooltip=['pais:N', 'cum_deaths:Q', 'cum_cases:Q']
).properties(
    width=700,
    height=400
).interactive()
source = source.where(source['max_cases'] >= 1000)

alt.Chart(source).mark_circle(size=100).encode(
    alt.X('cum_cases:Q'),
    alt.Y('cum_deaths:Q'),
    color='pais',
    tooltip=['pais:N', 'cum_deaths:Q', 'cum_cases:Q']
).properties(
    width=700,
    height=400
).interactive()

Argentina

Curva de casos acumulados por día

# select a point for which to provide details-on-demand
source = df.where(df['pais'] == 'Argentina')
label = alt.selection_single(
    encodings=['x'], # limit selection to x-axis value
    on='mouseover',  # select on mouseover events
    nearest=True,    # select data point nearest the cursor
    empty='none'     # empty selection includes no data points
)

# define our base line chart of stock prices
base = alt.Chart().mark_line().encode(
    alt.X('days:Q'),
    alt.Y('cum_cases:Q', scale=alt.Scale(type='log')),
    alt.Color('pais:N')
)

alt.layer(
    base, # base line chart
    
    # add a rule mark to serve as a guide line
    alt.Chart().mark_rule(color='#aaa').encode(
        x='days:Q'
    ).transform_filter(label),
    
    # add circle marks for selected time points, hide unselected points
    base.mark_circle().encode(
        opacity=alt.condition(label, alt.value(1), alt.value(0))
    ).add_selection(label),

    # add white stroked text to provide a legible background for labels
    base.mark_text(align='left', dx=5, dy=-5, stroke='white', strokeWidth=2).encode(
        text='cum_cases:Q'
    ).transform_filter(label),

    # add text labels for stock prices
    base.mark_text(align='left', dx=5, dy=-5).encode(
        text='cum_cases:Q'
    ).transform_filter(label),
    
    data=source
).properties(
    width=700,
    height=400
)
# select a point for which to provide details-on-demand
source = df.where(df['pais'] == 'Argentina')
label = alt.selection_single(
    encodings=['x'], # limit selection to x-axis value
    on='mouseover',  # select on mouseover events
    nearest=True,    # select data point nearest the cursor
    empty='none'     # empty selection includes no data points
)

# define our base line chart of stock prices
base = alt.Chart().mark_line().encode(
    alt.X('days:Q'),
    alt.Y('cum_deaths:Q'),
    alt.Color('pais:N')
)

alt.layer(
    base, # base line chart
    
    # add a rule mark to serve as a guide line
    alt.Chart().mark_rule(color='#aaa').encode(
        x='days:Q'
    ).transform_filter(label),
    
    # add circle marks for selected time points, hide unselected points
    base.mark_circle().encode(
        opacity=alt.condition(label, alt.value(1), alt.value(0))
    ).add_selection(label),

    # add white stroked text to provide a legible background for labels
    base.mark_text(align='left', dx=5, dy=-5, stroke='white', strokeWidth=2).encode(
        text='cum_deaths:Q'
    ).transform_filter(label),

    # add text labels for stock prices
    base.mark_text(align='left', dx=5, dy=-5).encode(
        text='cum_deaths:Q'
    ).transform_filter(label),
    
    data=source
).properties(
    width=700,
    height=400
)

Casos detectados por día

source = df.where(df['pais'] == 'Argentina')

alt.Chart(source).mark_line(point=True).encode(
    alt.X('dateRep:T'),
    alt.Y('cases:Q', scale=alt.Scale(type='log')),
    color='pais',
    tooltip=['pais:N', 'dateRep:T', 'cum_cases:Q']
).properties(
    width=700,
    height=400)